package com.zhanjixun.weixin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.zhanjixun.weixin.domain.*;
import com.zhanjixun.weixin.service.WxService;
import com.zhanjixun.weixin.utils.HttpTools;
import com.zhanjixun.weixin.utils.U;
import lombok.Getter;
import lombok.extern.log4j.Log4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;

import javax.activation.MimetypesFileTypeMap;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 网页微信HTTP接口基于org.apache.http.client.HttpClient的实现
 *
 * @author :zhanjixun
 * @date : 2018/11/18 11:11
 */
@Log4j
public class WxServiceImpl implements WxService {

    private String urlVersion;

    private WxTicket wxTicket;
    @Getter
    private JSONObject syncKey;

    private String redirectUri;

    private String userName;

    private JSONObject baseRequest;

    @Override
    public String getUUID() {
        HttpResponse httpResponse = HttpTools.get("https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&fun=new&lang=zh_CN&_=" + U.timeMillis());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String content = HttpTools.toUTF8String(httpResponse);
            return StringUtils.substringBetween(content, "window.QRLogin.uuid = \"", "\";");
        }
        return null;
    }

    @Override
    public BufferedImage getQRCodeImage(String uuid) {
        HttpResponse httpResponse = HttpTools.get("https://login.weixin.qq.com/qrcode/" + uuid);
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return HttpTools.readImage(httpResponse);
        }
        return null;
    }

    @Override
    public Map<String, String> getScanStatus(String uuid) {
        HttpResponse httpResponse = HttpTools.get("https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&tip=0&uuid=" + uuid + "&_=" + U.timeMillis() + "&r=" + U.r());
        Map<String, String> result = Maps.newHashMap();
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String response = HttpTools.toUTF8String(httpResponse);
            if (response.startsWith("window.code=201;")) {
                String userAvatar = StringUtils.substringBetween(response, "window.userAvatar = '", "';");
                result.put("code", "201");
                result.put("userAvatar", userAvatar);
            }
            if (response.startsWith("window.code=200;")) {
                redirectUri = StringUtils.substringBetween(response, "window.redirect_uri=\"", "\";");
                urlVersion = StringUtils.substringBetween(redirectUri, "://wx", ".qq.com/");
                result.put("code", "200");
                result.put("redirectUri", redirectUri);
            }
            if (response.startsWith("window.code=408;")) {
                result.put("code", "408");
            }
            if (response.startsWith("window.code=400;")) {
                result.put("code", "400");
            }
        }

        return result;
    }

    @Override
    public WxTicket getWxTicket() {
        HttpResponse httpResponse = HttpTools.getNoRedirect(redirectUri);

        String text = HttpTools.toUTF8String(httpResponse);
        wxTicket = WxTicket.valueOf(text);

        baseRequest = new JSONObject();
        baseRequest.put("Uin", wxTicket.getWxuin());
        baseRequest.put("Sid", wxTicket.getWxsid());
        baseRequest.put("Skey", wxTicket.getSkey());
        baseRequest.put("DeviceID", U.randomDeviceID());
        return wxTicket;
    }

    @Override
    public WxInitDataDTO webWxInit() {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxinit?lang=zh_CN&pass_ticket=%s&r=%s", urlVersion, U.urlEncode(wxTicket.getPassTicket()), U.r());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("BaseRequest", baseRequest);

        HttpResponse httpResponse = HttpTools.post(url, jsonObject.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            JSONObject initMap = JSON.parseObject(HttpTools.toUTF8String(httpResponse));
            syncKey = initMap.getJSONObject("SyncKey");
            userName = initMap.getJSONObject("User").getString("UserName");
            return initMap.toJavaObject(WxInitDataDTO.class);
        }
        return null;
    }

    @Override
    public void statusNotify() {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=%s", urlVersion, U.urlEncode(wxTicket.getPassTicket()));

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("ClientMsgId", System.currentTimeMillis());
        root.put("FromUserName", userName);
        root.put("ToUserName", userName);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            //log.info(JSON.parseObject(text).toJSONString());
        }
    }


    @Override
    public List<ContactMember> getContact() {
        String uri = "https://wx#{urlVersion}.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=#{pass_ticket}&seq=0&skey=#{skey}&r=#{r}";
        uri = uri.replace("#{urlVersion}", urlVersion);
        uri = uri.replace("#{pass_ticket}", U.urlEncode(wxTicket.getPassTicket()));
        uri = uri.replace("#{skey}", wxTicket.getSkey());
        uri = uri.replace("#{r}", U.timeMillis());

        HttpResponse httpResponse = HttpTools.get(uri);
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            JSONObject jsonObject = JSON.parseObject(HttpTools.toUTF8String(httpResponse));
            return JSON.parseArray(jsonObject.getJSONArray("MemberList").toJSONString(), ContactMember.class);
        }
        return null;
    }

    @Override
    public SyncCheck syncCheck() {
        String syncKeyStr = syncKey.getJSONArray("List").stream().map(d -> (JSONObject) d).map(d -> d.getString("Key") + "_" + d.getString("Val")).collect(Collectors.joining("|"));

        String url = "https://webpush.wx#{urlVersion}.qq.com/cgi-bin/mmwebwx-bin/synccheck?skey=#{skey}&sid=#{sid}&uin=#{uin}&synckey=#{synckey}&r=#{r}&_=#{_}";
        url = url.replace("#{urlVersion}", urlVersion);
        url = url.replace("#{skey}", U.urlEncode(wxTicket.getSkey()));
        url = url.replace("#{sid}", wxTicket.getWxsid());
        url = url.replace("#{uin}", wxTicket.getWxuin());
        url = url.replace("#{synckey}", U.urlEncode(syncKeyStr));
        url = url.replace("#{r}", U.timeMillis());
        url = url.replace("#{_}", U.timeMillis());

        HttpResponse httpResponse = HttpTools.get(url);
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String response = HttpTools.toUTF8String(httpResponse);
            return JSON.parseObject(StringUtils.substringAfter(response, "window.synccheck="), SyncCheck.class);
        }
        return null;
    }

    @Override
    public WxSyncDTO webWxSync() {
        String url = "https://wx#{urlVersion}.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=#{sid}&skey=#{skey}&pass_ticket=#{pass_ticket}";
        url = url.replace("#{urlVersion}", urlVersion);
        url = url.replace("#{skey}", U.urlEncode(wxTicket.getSkey()));
        url = url.replace("#{sid}", wxTicket.getWxsid());
        url = url.replace("#{pass_ticket}", U.urlEncode(wxTicket.getPassTicket()));

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("SyncKey", syncKey);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            syncKey = jsonObject.getJSONObject("SyncKey");
            return JSON.parseObject(text, WxSyncDTO.class);
        }
        return null;
    }

    @Override
    public WxMsg webWxSendMsg(String toUserName, String content, int msgType) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=%s", urlVersion, U.urlEncode(wxTicket.getPassTicket()));

        JSONObject msg = new JSONObject();
        String localId = System.currentTimeMillis() + RandomStringUtils.randomNumeric(4);
        msg.put("ClientMsgId", localId);
        msg.put("LocalID", localId);
        msg.put("FromUserName", userName);
        msg.put("ToUserName", toUserName);
        msg.put("Content", content);
        msg.put("Type", msgType);

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("Scene", 0);
        root.put("Msg", msg);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            if (jsonObject.getJSONObject("BaseResponse").getInteger("Ret") != 0) {
                log.warn("发送消息异常：" + jsonObject.getJSONObject("BaseResponse").getString("ErrMsg"));
            } else {
                //log.info("发送消息：" + content);
                WxMsg wxMsg = new WxMsg();
                wxMsg.setMsgType(msgType);
                wxMsg.setMsgId(jsonObject.getString("MsgID"));
                wxMsg.setContent(content);
                wxMsg.setFromUserName(userName);
                wxMsg.setToUserName(toUserName);
                return wxMsg;
            }
        }
        return null;
    }

    @Override
    public boolean webWxRevokeMsg(String msgID, String toUserName) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxrevokemsg", urlVersion);

        String localId = System.currentTimeMillis() + RandomStringUtils.randomNumeric(4);
        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("SvrMsgId", msgID);
        root.put("ToUserName", toUserName);
        root.put("ClientMsgId", localId);//看了网页版微信这个参数发的是发消息时候的ClientMsgId，但是这里再组装一个过去也能成功

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            if (jsonObject.getJSONObject("BaseResponse").getInteger("Ret") != 0) {
                log.warn("撤回消息失败：" + jsonObject.toJSONString());
                return false;
            } else {
                return true;
            }
        }
        return false;
    }

    @Override
    public String webWxUploadMedia(String toUserName, byte[] data, String fileName) {
        String url = String.format("https://file.wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json", urlVersion);

        JSONObject uploadMediaRequest = new JSONObject();
        uploadMediaRequest.put("UploadType", 2);
        uploadMediaRequest.put("BaseRequest", baseRequest);
        uploadMediaRequest.put("ClientMediaId", System.currentTimeMillis());
        uploadMediaRequest.put("TotalLen", data.length);
        uploadMediaRequest.put("StartPos", 0);
        uploadMediaRequest.put("DataLen", data.length);
        uploadMediaRequest.put("MediaType", 4);
        uploadMediaRequest.put("FromUserName", userName);
        uploadMediaRequest.put("ToUserName", toUserName);
        uploadMediaRequest.put("FileMd5", DigestUtils.md5Hex(data));

        String mimeType = new MimetypesFileTypeMap().getContentType(fileName);
        String mediaType = mimeType == null ? "text/plain" : mimeType.split("/")[0].equals("image") ? "pic" : "doc";
        //String lastModified = new SimpleDateFormat("yyyy MM dd HH:mm:ss").format(new Date());

        // 分片数量
        int chunks = new BigDecimal(data.length).divide(new BigDecimal(MEDIA_CHUNK_SIZE), 0, BigDecimal.ROUND_UP).intValue();
        String mediaId = null;
        for (int chunk = 0; chunk < chunks; chunk++) {
            int from = chunk * MEDIA_CHUNK_SIZE;
            int to = Math.min((chunk + 1) * MEDIA_CHUNK_SIZE, data.length);
            byte[] chunkData = Arrays.copyOfRange(data, from, to);

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            builder.addTextBody("id", "WU_FILE_0", ContentType.TEXT_PLAIN);
            builder.addTextBody("name", fileName, ContentType.TEXT_PLAIN);
            builder.addTextBody("type", mimeType, ContentType.TEXT_PLAIN);
            builder.addTextBody("lastModifiedDate", String.valueOf(System.currentTimeMillis()), ContentType.TEXT_PLAIN);
            builder.addTextBody("size", String.valueOf(data.length), ContentType.TEXT_PLAIN);
            builder.addTextBody("mediatype", mediaType, ContentType.TEXT_PLAIN);

            //上传图片和视频都需要这两个参数
            builder.addTextBody("chunks", String.valueOf(chunks));
            builder.addTextBody("chunk", String.valueOf(chunk));

            builder.addTextBody("uploadmediarequest", uploadMediaRequest.toJSONString(), ContentType.TEXT_PLAIN);
            builder.addTextBody("webwx_data_ticket", HttpTools.getCookie("webwx_data_ticket"), ContentType.TEXT_PLAIN);
            builder.addTextBody("pass_ticket", wxTicket.getPassTicket(), ContentType.TEXT_PLAIN);
            builder.addBinaryBody("filename", chunkData, ContentType.create(mimeType), fileName);

            HttpResponse httpResponse = HttpTools.post(url, builder.build());
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String text = HttpTools.toUTF8String(httpResponse);
                JSONObject jsonObject = JSON.parseObject(text);
                log.info(String.format("上传文件(%s)：%.2f%%", fileName, ((chunkData.length + MEDIA_CHUNK_SIZE * chunk) / (double) data.length) * 100));
                //发现ret 1205 也有传回MediaId
                mediaId = jsonObject.getString("MediaId");
            }
        }
        return mediaId;

    }

    @Override
    public String webWxUploadMedia(String toUserName, File file) {
        String url = String.format("https://file.wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json", urlVersion);

        JSONObject uploadMediaRequest = new JSONObject();
        uploadMediaRequest.put("UploadType", 2);
        uploadMediaRequest.put("BaseRequest", baseRequest);
        uploadMediaRequest.put("ClientMediaId", System.currentTimeMillis());
        uploadMediaRequest.put("TotalLen", file.length());
        uploadMediaRequest.put("StartPos", 0);
        uploadMediaRequest.put("DataLen", file.length());
        uploadMediaRequest.put("MediaType", 4);
        uploadMediaRequest.put("FromUserName", userName);
        uploadMediaRequest.put("ToUserName", toUserName);
        try {
            uploadMediaRequest.put("FileMd5", DigestUtils.md5Hex(new FileInputStream(file)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //TODO 一次性读取文件可能会内存溢出
        byte[] mediaData = U.readFile(file);

        String mimeType = new MimetypesFileTypeMap().getContentType(file);
        String mediaType = mimeType == null ? "text/plain" : mimeType.split("/")[0].equals("image") ? "pic" : "doc";
        String lastModified = new SimpleDateFormat("yyyy MM dd HH:mm:ss").format(file.lastModified());

        // 分片数量
        int chunks = new BigDecimal(file.length()).divide(new BigDecimal(MEDIA_CHUNK_SIZE), 0, BigDecimal.ROUND_UP).intValue();
        String mediaId = null;
        for (int chunk = 0; chunk < chunks; chunk++) {
            int from = chunk * MEDIA_CHUNK_SIZE;
            int to = Math.min((chunk + 1) * MEDIA_CHUNK_SIZE, (int) file.length());
            byte[] temp = Arrays.copyOfRange(mediaData, from, to);
            //byte[] temp = U.readFile(file, from, to);

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            builder.addTextBody("id", "WU_FILE_0", ContentType.TEXT_PLAIN);
            builder.addTextBody("name", file.getName(), ContentType.TEXT_PLAIN);
            builder.addTextBody("type", mimeType, ContentType.TEXT_PLAIN);
            builder.addTextBody("lastModifiedDate", lastModified, ContentType.TEXT_PLAIN);
            builder.addTextBody("size", String.valueOf(file.length()), ContentType.TEXT_PLAIN);
            builder.addTextBody("mediatype", mediaType, ContentType.TEXT_PLAIN);

            //上传图片和视频都需要这两个参数
            builder.addTextBody("chunks", String.valueOf(chunks));
            builder.addTextBody("chunk", String.valueOf(chunk));

            builder.addTextBody("uploadmediarequest", uploadMediaRequest.toJSONString(), ContentType.TEXT_PLAIN);
            builder.addTextBody("webwx_data_ticket", HttpTools.getCookie("webwx_data_ticket"), ContentType.TEXT_PLAIN);
            builder.addTextBody("pass_ticket", wxTicket.getPassTicket(), ContentType.TEXT_PLAIN);
            builder.addBinaryBody("filename", temp, ContentType.create(mimeType), file.getName());

            HttpResponse httpResponse = HttpTools.post(url, builder.build());
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String text = HttpTools.toUTF8String(httpResponse);
                JSONObject jsonObject = JSON.parseObject(text);
                log.info(String.format("上传文件(%s)：%.2f%%", file.getName(), ((temp.length + MEDIA_CHUNK_SIZE * chunk) / (double) file.length()) * 100));
                mediaId = jsonObject.getString("MediaId");
            }
        }
        return mediaId;
    }

    @Override
    public WxMsg webWxSendAppMsg(String toUserName, String fileName, long fileLen, String fileExt, String mediaId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxsendappmsg?fun=async&f=json", urlVersion);

        StringBuilder content = new StringBuilder();

        content.append("<appmsg appid='wxeb7ec651dd0aefa9' sdkver=''>");
        content.append(String.format("<title>%s</title>", fileName));
        content.append("<des></des>");
        content.append("<action></action>");
        content.append("<type>6</type>");
        content.append("<content></content>");
        content.append("<url></url>");
        content.append("<lowurl></lowurl>");
        content.append("<appattach>");
        content.append(String.format("<totallen>%s</totallen>", fileLen));
        content.append(String.format("<attachid>%s</attachid>", mediaId));
        content.append(String.format("<fileext>%s</fileext>", fileExt));
        content.append("</appattach>");
        content.append("<extinfo></extinfo>");
        content.append("</appmsg>");

        String localId = System.currentTimeMillis() + RandomStringUtils.randomNumeric(4);
        JSONObject msg = new JSONObject();
        msg.put("ClientMsgId", localId);
        msg.put("LocalID", localId);
        msg.put("FromUserName", userName);
        msg.put("ToUserName", toUserName);
        msg.put("Content", content.toString());
        msg.put("Type", 6);

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("Scene", 0);
        root.put("Msg", msg);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            //log.info(jsonObject.toJSONString());
            if (jsonObject.getJSONObject("BaseResponse").getInteger("Ret") != 0) {
                log.warn("发送文件异常：" + jsonObject.toJSONString());
            } else {
                WxMsg wxMsg = new WxMsg();
                wxMsg.setMsgType(6);
                wxMsg.setMediaId(mediaId);
                wxMsg.setMsgId(jsonObject.getString("MsgID"));
                wxMsg.setContent(content.toString());
                wxMsg.setFromUserName(userName);
                wxMsg.setToUserName(toUserName);
                return wxMsg;
            }
        }
        return null;
    }

    @Override
    public WxMsg webWxSendMsgImg(String toUserName, String mediaId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=%s", urlVersion, U.urlEncode(wxTicket.getPassTicket()));

        JSONObject msg = new JSONObject();
        String localId = System.currentTimeMillis() + RandomStringUtils.randomNumeric(4);
        msg.put("ClientMsgId", localId);
        msg.put("LocalID", localId);
        msg.put("FromUserName", userName);
        msg.put("ToUserName", toUserName);
        msg.put("Content", "");
        msg.put("MediaId", mediaId);
        msg.put("Type", 3);

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("Scene", 0);
        root.put("Msg", msg);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            if (jsonObject.getJSONObject("BaseResponse").getInteger("Ret") != 0) {
                log.warn("发送图片消息异常：" + jsonObject.toJSONString());
            } else {
                //log.debug("发送图片消息：" + jsonObject.toJSONString());
                WxMsg wxMsg = new WxMsg();
                wxMsg.setMsgType(3);
                wxMsg.setMediaId(mediaId);
                wxMsg.setMsgId(jsonObject.getString("MsgID"));
                wxMsg.setFromUserName(userName);
                wxMsg.setToUserName(toUserName);
                return wxMsg;
            }
        }
        return null;
    }

    @Override
    public WxMsg webWxSendVideoMsg(String toUserName, String mediaId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxsendvideomsg?fun=async&f=json&lang=zh_CN&pass_ticket=%s", urlVersion, U.urlEncode(wxTicket.getPassTicket()));

        JSONObject msg = new JSONObject();
        String localId = System.currentTimeMillis() + RandomStringUtils.randomNumeric(4);
        msg.put("Type", 43);
        msg.put("MediaId", mediaId);
        msg.put("Content", "");
        msg.put("FromUserName", userName);
        msg.put("ToUserName", toUserName);
        msg.put("LocalID", localId);
        msg.put("ClientMsgId", localId);

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("Scene", 0);
        root.put("Msg", msg);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            if (jsonObject.getJSONObject("BaseResponse").getInteger("Ret") != 0) {
                log.warn("发送视频消息异常：" + jsonObject.toJSONString());
            } else {
                WxMsg wxMsg = new WxMsg();
                wxMsg.setMsgType(43);
                wxMsg.setMediaId(mediaId);
                wxMsg.setMsgId(jsonObject.getString("MsgID"));
                wxMsg.setFromUserName(userName);
                wxMsg.setToUserName(toUserName);
                return wxMsg;
            }
        }
        return null;
    }

    @Override
    public WxMsg webWxSendEmoticon(String toUserName, String mediaId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxsendemoticon?fun=sys", urlVersion);

        JSONObject msg = new JSONObject();
        String localId = System.currentTimeMillis() + RandomStringUtils.randomNumeric(4);
        msg.put("Type", 47);
        msg.put("EmojiFlag", 2);
        msg.put("MediaId", mediaId);
        msg.put("FromUserName", userName);
        msg.put("ToUserName", toUserName);
        msg.put("LocalID", localId);
        msg.put("ClientMsgId", localId);

        JSONObject root = new JSONObject();
        root.put("BaseRequest", baseRequest);
        root.put("Scene", 0);
        root.put("Msg", msg);

        HttpResponse httpResponse = HttpTools.post(url, root.toJSONString());
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String text = HttpTools.toUTF8String(httpResponse);
            JSONObject jsonObject = JSON.parseObject(text);
            if (checkBaseResponse(jsonObject)) {
                WxMsg wxMsg = new WxMsg();
                wxMsg.setMsgType(47);
                wxMsg.setMediaId(mediaId);
                wxMsg.setMsgId(jsonObject.getString("MsgID"));
                wxMsg.setFromUserName(userName);
                wxMsg.setToUserName(toUserName);
                return wxMsg;
            }
            log.warn("发送动画表情异常：" + jsonObject.toJSONString());
        }
        return null;
    }

    @Override
    public File webWxGetMsgImg(String msgId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg?MsgID=%s&skey=%s", urlVersion, msgId, U.urlEncode(wxTicket.getSkey()));
        HttpResponse httpResponse = HttpTools.get(url);
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return HttpTools.downloadFile(httpResponse, msgId);
        }
        return null;
    }

    @Override
    public File webWxGetVoice(String msgId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxgetvoice?msgid=%s&skey=%s", urlVersion, msgId, U.urlEncode(wxTicket.getSkey()));
        HttpResponse httpResponse = HttpTools.get(url);
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return HttpTools.downloadFile(httpResponse, msgId);
        }
        return null;
    }

    @Override
    public File webWxGetMedia(String fromUserName, String mediaId) {

        return null;
    }

    @Override
    public File webWxGetPublicLinkImg(String msgId) {
        String url = String.format("https://wx%s.qq.com/cgi-bin/mmwebwx-bin/webwxgetpubliclinkimg?url=xxx&msgid=%s&pictype=location", urlVersion, msgId);
        HttpResponse httpResponse = HttpTools.get(url);
        if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            return HttpTools.downloadFile(httpResponse, msgId);
        }
        return null;
    }

    @Override
    public File webWxGetIcon() {
//        普通获取头像
//        https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgeticon?seq=681954301&username=@97b805f65ecbee7dc03aaa058a3db72f7744f0d50e85751bd02c3e1e5f26f865&skey=@crypt_fb53c65e_e8817db6cf9e96caacea2c977d19513d&type=big

//        群聊获取头像
//        https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@642255e05b14eeddca1937d695a7fef114b13e457fed21733cd2a6a10d95387e&chatroomid=@ca749c1846adafbbe665cbe88fa23cc7&skey=

        return null;
    }

    private boolean checkBaseResponse(JSONObject root) {
        return root.getJSONObject("BaseResponse").getInteger("Ret") == 0;
    }
}
